package com.service;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Date;

import org.junit.Test;

import com.bean.User;
import com.sxt.A;

public class Demo {
	
	/**
	 * 获取Class对象方式
	 * 1.Class<?> clazz = Class.forName(String className);
	 * 2.Class<?> clazz = T.class;
	 * @throws Exception
	 */
	@Test
	public void test1() throws Exception{
		Class<?> clazz1 = Class.forName("com.bean.User");
		System.out.println(clazz1);
		Class<?> clazz2 = User.class;
		System.out.println(clazz2);
	}

	/**
	 * 获取所有构造器，并且获得构造器参数类型
	 * @throws Exception
	 */
	@Test
	public void test2() throws Exception{
		Class<?> clazz = User.class;
		Constructor<?>[] cons = clazz.getConstructors();
		for(Constructor<?> constemp : cons) {
			System.out.println(Arrays.toString(constemp.getParameterTypes()));
		}
	}
	
	/**
	 * 
	 * @throws Exception
	 */
	@Test
	public void test3() throws Exception {
		Class<?> clazz = User.class;
		Constructor<?> cons = clazz.getConstructor(int.class,String.class, String.class);
		User user = (User)cons.newInstance(10,"Jerry", "男");
		System.out.println(user);
	}
	
	@Test
	public void test4() throws Exception {
		Class<?> clazz = A.class;
//		Constructor<?>[] cons = clazz.getConstructors();
//		for (Constructor<?> constructor : cons) {
//			/*
//			 * [double, float]
//			 * [int, class java.lang.String, int]
//			 * [class java.util.Date, class java.lang.String]
//			 */
//			System.out.println(Arrays.toString(constructor.getParameterTypes()));
//		}
		
		Constructor<?> cons1 = clazz.getConstructor(double.class, float.class);
		A a1 = (A)cons1.newInstance(100.1, 100.3f);
		System.out.println(a1);
		Constructor<?> cons2 = clazz.getConstructor(int.class, String.class, int.class);
		A a2 = (A)cons2.newInstance(2, "Hello World", 15);
		System.out.println(a2);
		Constructor<?> cons3 = clazz.getConstructor(Date.class, String.class);
		A a3 = (A)cons3.newInstance(new Date(), "Hello World");
		System.out.println(a3);
	}
	
	@Test
	public void test5() throws Exception {
		Class<?> clazz = Class.forName("com.bean.User");
		//获得所有声明的方法，包括私有方法
		Method[] methods = clazz.getDeclaredMethods();
		for (Method method : methods) {
			/*
		 		class java.lang.String getName []
				void setName [class java.lang.String]
				void study []
				class java.lang.String say [class java.lang.String]
				void setAge [int]
				int getAge []
			 */
			System.out.println(method.getReturnType() + " " + method.getName() + " " + Arrays.toString(method.getParameterTypes()));
		}
		
		Method m = clazz.getMethod("study");
		//先产生类的对象
		Constructor<?> cons = clazz.getConstructor();
		User user = (User)cons.newInstance();
		//invoke执行类的方法
		m.invoke(user);
		Method m1 = clazz.getDeclaredMethod("talk", String.class);
		m1.setAccessible(true);//设置私有方法为可以访问
		String result = (String)m1.invoke(user, "张三");
		System.out.println(result);
	}
	
	@Test
	public void test6() throws Exception {
		Class<?> clazz = Class.forName("com.bean.User");
		Field[] fields = clazz.getDeclaredFields();
		for (Field field : fields) {
			/*
			 private int com.bean.User.age
			 private java.lang.String com.bean.User.name
			 public java.lang.String com.bean.User.gender
			 */
			System.out.println(field);
		}
		Constructor<?> cons = clazz.getConstructor();
		User user = (User)cons.newInstance();
		
		Field field = clazz.getDeclaredField("age");
		field.setAccessible(true);
		field.set(user, 10);
		System.out.println(field.getType());
	}
}

